package com.zoe.vhr.config;

import com.zoe.vhr.enums.MailConfigEnum;
import com.zoe.vhr.service.MailSendLogService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;

/**
 * @author zoe.Zhang
 * @date 2022/06/21
 * @description RabbitTemplate.ConfirmCallback 交换器确认接口
 *         想让这个回调生效必须在配置文件里面配置 spring.rabbitmq.publisher-confirm-type: correlated 表示开启交换机确认模式
 *         RabbitTemplate.ReturnCallback  消息回退接口
 *         想让这个回调生效需要在application配置文件开启Mandatory参数（ spring.rabbitmq.template.mandatory= true 消息回退）
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class RabbitCallBackZOE implements RabbitTemplate.ReturnCallback {

    @Resource
    private RabbitTemplate rabbitTemplate;

    @Resource
    private MailSendLogService mailSendLogService;

    @PostConstruct
    public void init() {
        rabbitTemplate.setReturnCallback(this);
    }


    /**
     * 交换机 -> 队列 这个步骤(当交换机不能把消息路由到队列上的时候才会触发)
     *
     * @param message    the returned message.
     * @param replyCode  the reply code.
     * @param replyText  the reply text.
     * @param exchange   the exchange.
     * @param routingKey the routing key.
     */
    @Override
    public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
        String msgId = message.getMessageProperties().getHeader(MailConfigEnum.CONSUMER_MSG_ID).toString();
        mailSendLogService.updateSendLog(msgId, MailConfigEnum.SENDING);
        log.info("\n 消息回退:无法路由的消息 {} \n 响应码 ===> {} \n 被交换机 ===> {} \n 退回的原因是 ===> {} \n 路由key是 ===> {} \n 消息内容 ===>{}", msgId, replyCode, exchange, replyText, routingKey, message.toString());
    }
}
